qemu启动pve qcow2虚拟机镜像排查

·

修复qcow2文件目录

最后发现时rootfs中缺少了 /dev 和 /sys 两个目录,导致initrd中切换到systemd时缺少挂载点后panic了

qemu-system-x86_64 --enable-kvm -smp 2 -m 4096  -hda vm-7044.qcow2 -snapshot -serial stdio
modprobe nbd
sudo modprobe nbd max_part=8
lsblk
qemu-nbd --help
qemu-nbd -c /dev/nbd0 vm-7044.qcow2
mkdir vm-7044 && cd vm-7044/
mkdir part{1,5}
mount /dev/nbd0p1 part1/
mount /dev/nbd0p5 part5
cd part5/boot/
file initrd.img
mkdir initrd && cd initrd/
cpio -idmv < ../initrd.img-5.15.0-139-generic
qemu-system-x86_64 -smp 2 -m 4096 -kernel vmlinuz-5.15.0-139-generic -initrd initrd.img-5.15.0-139-generic  -append "console=ttyS0"
cp initrd.img ../../
cp vmlinuz ../../
umount part1
umount part5
qemu-nbd -d /dev/nbd0
qemu-system-x86_64 --enable-kvm -smp 2 -m 4096 -kernel vmlinuz -initrd initrd.img  -append "console=ttyS0"
qemu-system-x86_64 --enable-kvm -smp 2 -m 4096  -hda ../vm-7044.qcow2
qemu-system-x86_64 --enable-kvm -smp 2 -m 4096 -kernel vmlinuz -initrd initrd.img  -append "console=ttyS0" -hda ../vm-7044.qcow2
qemu-system-x86_64 --enable-kvm -smp 2 -m 4096 -kernel vmlinuz -initrd initrd.img  -append "console=ttyS0 root=/dev/sda5" -hda ../vm-7044.qcow2

# 最后发现qcow2中的文件系统缺少/dev 和 /sys 两个目录(导致init启动时没有devfs/tmpfs的挂载点)
qemu-system-x86_64 --enable-kvm -smp 2 -m 4096 -hda vm-7044.qcow2

qemu虚拟机启动后如何切换tty

  • tty1中的启动程序没有完全成功,导致卡死在启动过程,且没有shell供用户输入
  • qemu GUI中使用monitor0, 可以发送命令,切换其他tty登录
(qemu) sendkey ctrl+alt+f3

# 登录系统后, 修改grub
sudo nano /etc/defautl/grub
# 注释掉hide和选项
# GRUB_TIMEOUT_STYLE=hide
GRUB_CMDLINE_LINUX_DEFAULT='loglevel=7'
GRUB_CMDLINE_LINUX="console=tty0 console=ttyS0,115200n8 earlyprintk=ttyS0,115200 systemd.show_status=1"

sudo update-grub

grub shell常用命令

  • ls 列出设备、分区或目录内容 ls, ls (hd0,1)/boot
  • set 查看或设置环境变量 set root=(hd0,gpt2)
  • linux 加载内核文件 linux /vmlinuz root=/dev/sda5
  • initrd 加载初始化 RAM 磁盘 initrd /initrd.img
  • boot 启动已经加载好的内核 boot
  • insmod 加载动态模块(如 normal, ext2) insmod normal
  • cat 查看文件内容(常用于检查 grub.cfg) cat (hd0,1)/etc/default/grub
grub> configfile (hd0,msdos1)/boot/grub/grub.cfg
# 或尝试使用 search 命令自动查找
grub> search --file --set=root /boot/grub/grub.cfg
grub> configfile /boot/grub/grub.cfg

grub> ls (hd0,msdos5)/
# 如果显示了 vmlinuz, initrd.img 等文件,说明找对了

# 第二步:设置根分区
# 查看当前 root / prefix
grub> set
grub> set root=(hd0,msdos5)
grub> insmod normal
grub> insmod linux
grub> insmod ext2     # ext2/ext4 都是这个

# 第三步:加载内核 (关键步骤)
# 你需要指定内核文件,并手动告诉它根目录在哪里。在这里加上 nomodeset 来解决你之前的卡死问题。
# 注意:利用 Tab 键补全文件名,因为内核版本号很长
grub> linux /boot/vmlinuz-xxx-generic root=/dev/sda5 nomodeset

# 第四步:加载 initrd
grub> initrd /boot/initrd.img-xxx-generic
grub> boot